package edu.lnu.ums.ui;

import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.http.HttpSession;

import edu.lnu.ums.dal.IUserDAO;
import edu.lnu.ums.dal.IUserDAO.UserValidationResult;
import edu.lnu.ums.entities.security.User;

public class UserBean {

	private static final long serialVersionUID = -4691257100940437225L;

	private static final String BUNDLE_NAME = "messages";

	private static final String ADMIN_START_PAGE = "admin";
	private static final String ADD_NEW_USER = "addNewUser";
	private static final String EDIT_USER = "editUser";
	private static final String DELETE_USER = "deleteUser";

	private static final String EXISTING_LOGIN_MESSAGE = "EXISTING_LOGIN_MESSAGE";
	private static final String BAD_LOGIN_MESSAGE = "BAD_LOGIN_MESSAGE";
	private static final String BAD_PASSWORD_MESSAGE = "BAD_PASSWORD_MESSAGE";

	private static final String USER_ROLE = "USER";
	private static final String ADMIN_ROLE = "ADMIN";

	private String oldEditLogin;
	private String selectedActive;

	@EJB(mappedName = "UMS/UserDAO/local")
	private IUserDAO userDAO;
	private User selectedUser;

	public List<User> getAllUsers() {

		try {
			selectedUser = new User();
			userDAO = (IUserDAO) InitialContext.doLookup("UMS/UserDAO/local");
		} catch (NamingException e) {
			e.printStackTrace();
		}
		return userDAO.getAllUsers();
	}

	public int getAllUsersSize() {
		return getAllUsers().size();
	}

	public String doAddNewUser() {
		User user = new User();
		user.setName(selectedUser.getName());
		user.setPassword(selectedUser.getPassword());
		user.setType(selectedUser.getType());
		UserValidationResult validationResult = userDAO.validateUser(user, user
				.getName());

		switch (validationResult) {
		case OK:
			userDAO.addUser(user);
			selectedActive = "";
			selectedUser = new User();
			return ADMIN_START_PAGE;
		case BAD_LOGIN:
			showMessage(null, BAD_LOGIN_MESSAGE, FacesMessage.SEVERITY_WARN);
			return ADD_NEW_USER;
		case BAD_PASSWORD:
			showMessage(null, BAD_PASSWORD_MESSAGE, FacesMessage.SEVERITY_WARN);
			return ADD_NEW_USER;
		case EXISTING_LOGIN:
			showMessage(null, EXISTING_LOGIN_MESSAGE,
					FacesMessage.SEVERITY_WARN);
			return ADD_NEW_USER;
		default:
			throw new RuntimeException("Unreachable code!");
		}
	}

	User getUser() {
		String login = FacesContext.getCurrentInstance().getExternalContext()
				.getRemoteUser();
		return userDAO.getByName(login);
	}

	public String goToAddNewUser() {
		return ADD_NEW_USER;
	}

	public String goToEditUser() {
		UIComponent comp = FacesContext.getCurrentInstance().getViewRoot()
				.findComponent("table:userstable");
		HtmlDataTable dataTable = (HtmlDataTable) comp;
		User user = (User) dataTable.getRowData();
		selectedUser = userDAO.getByName(user.getName());
		oldEditLogin = selectedUser.getName();
		selectedActive = selectedUser.getActive().toString();
		return EDIT_USER;
	}

	public String goToDeleteUser() {
		UIComponent comp = FacesContext.getCurrentInstance().getViewRoot()
				.findComponent("table:userstable");
		HtmlDataTable dataTable = (HtmlDataTable) comp;
		User user = (User) dataTable.getRowData();
		selectedUser = userDAO.getByName(user.getName());
		selectedActive = selectedUser.getActive().toString();
		return DELETE_USER;
	}

	public User getSelectedUser() {
		return selectedUser;
	}

	public void setSelectedUser(User selectedUser) {
		this.selectedUser = selectedUser;
	}

	public String getSelectedActive() {
		return selectedActive;
	}

	public void setSelectedActive(String selectedActive) {
		this.selectedActive = selectedActive;
	}

	public List<SelectItem> getAllRoleNames() {
		List<String> roles = new ArrayList<String>();
		roles.add(USER_ROLE);
		roles.add(ADMIN_ROLE);
		return transformCollection(roles);
	}

	public List<SelectItem> getAllActivities() {
		List<String> activities = new ArrayList<String>();
		activities.add("true");
		activities.add("false");
		return transformCollection(activities);
	}

	public String cancelAdding() {
		selectedActive = "";
		selectedUser = new User();
		return ADMIN_START_PAGE;
	}

	private List<SelectItem> transformCollection(List<?> list) {
		List<SelectItem> items = new ArrayList<SelectItem>();

		for (Object obj : list) {
			items.add(new SelectItem(obj));
		}

		return items;
	}

	public String doEditUser() {
		User user = new User();
		user.setId(selectedUser.getId());
		user.setName(selectedUser.getName());
		user.setPassword(selectedUser.getPassword());
		user.setType(selectedUser.getType());
		user.setActive(Boolean.valueOf(selectedActive));
		UserValidationResult validationResult = userDAO.validateUser(user,
				oldEditLogin);

		switch (validationResult) {
		case OK:
			userDAO.editUser(user);
			selectedActive = "";
			selectedUser = new User();
			return ADMIN_START_PAGE;
		case BAD_LOGIN:
			showMessage(null, BAD_LOGIN_MESSAGE, FacesMessage.SEVERITY_WARN);
			return EDIT_USER;
		case BAD_PASSWORD:
			showMessage(null, BAD_PASSWORD_MESSAGE, FacesMessage.SEVERITY_WARN);
			return EDIT_USER;
		case EXISTING_LOGIN:
			userDAO.editUser(user);
			selectedActive = "";
			selectedUser = new User();
			return ADMIN_START_PAGE;
		case EXISTING_EDIT_LOGIN:
			showMessage(null, EXISTING_LOGIN_MESSAGE,
					FacesMessage.SEVERITY_WARN);
			return EDIT_USER;
		default:
			throw new RuntimeException("Unreachable code!");
		}
	}

	public String doDeleteUser() {
		User user = new User();
		user.setId(selectedUser.getId());
		user.setName(selectedUser.getName());
		user.setType(selectedUser.getType());
		user.setActive(Boolean.valueOf(selectedActive));
		userDAO.removeUser(user);
		selectedActive = "";
		selectedUser = new User();
		return ADMIN_START_PAGE;
	}

	public String getCurrentUserRole() {
		String login = FacesContext.getCurrentInstance().getExternalContext()
				.getRemoteUser();
		if ("".equals(login) || login == null) {
			return null;
		}

		User currentUser = userDAO.getByName(login);
		return currentUser.getType();
	}

	public void doExit() {
		HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
				.getExternalContext().getSession(true);
		session.invalidate();
	}

	private void showMessage(String clientId, String key,
			FacesMessage.Severity severity) {
		String text = null;

		try {
			ResourceBundle bundle = ResourceBundle
					.getBundle(BUNDLE_NAME, FacesContext.getCurrentInstance()
							.getViewRoot().getLocale());
			text = bundle.getString(key);
		} catch (Exception e) {
			System.out.println(e.toString());
		}

		FacesContext.getCurrentInstance().addMessage(clientId,
				new FacesMessage(severity, text, text));
	}
}
